home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Utilities / Unix / CopyPath / CopyPath.m < prev    next >
Text File  |  1992-01-08  |  4KB  |  157 lines

  1. /*
  2. CopyPath.m -- Services program for Workspace to make a cd command
  3.     using the current path, and copy that onto pasteboard in
  4.     plain ASCII.
  5.     This is for pasting in a cd command into a shell.
  6.     Copy in Workspace doesn't work for this purpose, because
  7.     the copied pathname is NXFilenamePboardType, rather than
  8.     NXAsciiPboardType required by Terminal and Stuart.
  9.  
  10.     This app has no GUI.
  11.  
  12.     No Copyright is claimed.
  13.     This program is hereby released into the public domain.
  14.  
  15. 10-30-91, Version 1.0  Izumi Ohzawa.
  16. 11-07-91, Condensed and modified by Daniel Faken - Main differences:
  17.      1) Optimised. (You ask Why? Why not.)
  18.      3) No Workspace-owned icon-tile pops up, due to a .daemon extension.
  19.      4) Doesn't exit after pasting. (Can't see it anyhow, so why exit?)
  20.      5) I ask that you keep at least brief mention of my name on this.
  21. 11-12-91, Version 1.1 Izumi Ohzawa.
  22.     Grafted back separate cd command making code, etc.
  23. 11-20-91, Version 1.2 Eric P. Scott.
  24.     Removed unused .h file.
  25.     Removed all references to Application Class.
  26.     Removed Window posing nonsense.
  27.     Converted internal method to C procedure.
  28.     Added more intelligent shell quoting.
  29.     Added pushd option.
  30. 1-08-92, Version 1.3 Michael Cohen (mcohen@acoustic-srx.ntt.jp)
  31.     Fixed for multiple browser selection.
  32. */
  33.  
  34. static char sccsid[]="@(#)CopyPath.m    1.3 (NTT, Tokyo) 1/8/92";
  35.  
  36. #import <stdlib.h>
  37. #import <appkit/Listener.h>
  38. #import <appkit/Pasteboard.h>
  39. #import <appkit/Speaker.h>
  40. #import <strings.h>
  41. #import <sys/stat.h>
  42. #import <sys/param.h>
  43.  
  44. char PathBuf[2*MAXPATHLEN+8];
  45.  
  46. @interface CopyPath:Object
  47. - copyAsciiPath:(id)pbid userData:(const char *)udata error:(char **)errmsg;
  48. - makeCdCommand:(id)pbid userData:(const char *)udata error:(char **)errmsg;
  49. - makePushdCommand:(id)pbid userData:(const char *)udata error:(char **)errmsg;
  50. @end
  51.  
  52. @implementation CopyPath
  53.  
  54. // mutant strcat that quotes shell metacharacters
  55. static char *shstrcat(register char *dst, register char *src)
  56. {
  57.     register char *p;
  58.     
  59.     while (*dst) dst++;
  60.     p=src;
  61.     if (*p=='~') *dst++='\\';    // csh "feature"
  62.     while (*p) {
  63.     if (*p<=' '||*p>'~'||index(";&()|<>\\'\"$*?[]^!", *p)) *dst++='\\';
  64.     *dst++=*p++;
  65.     }
  66.     *dst='\0';
  67.     return(src);
  68. }
  69.  
  70. // Real procedure to do work
  71. static void addPath(id pbid, const char *udata, char **errmsg, int flag)
  72. {
  73. char *path, *pathptr, *tabLoc; 
  74. int   length, i;
  75. char **types;
  76. struct stat filestat;
  77. static id spkr;
  78.  
  79.     PathBuf[0]='\0';
  80.     if(flag) (void)strcpy(PathBuf, flag==2 ? "pushd " : "cd ");
  81.  
  82.     (const char *const *)types = [pbid types];
  83.     for(i = 0; strcmp(types[i], NXFilenamePboardType) && types[i]; i++) ;
  84.     if(types[i])
  85.     {
  86.         [pbid readType:NXFilenamePboardType data:&path length:&length];
  87.         
  88.         // This isolates the first of possibly multiple paths
  89.         if (tabLoc = index(path, '\t'))
  90.         *tabLoc = '\0';
  91.  
  92.         if(path && length && !stat(path, &filestat))
  93.         {
  94.         // If not a directory, make it into a directory when making cd
  95.         // command.  Note that stat() follows symlinks.
  96.         if(flag) {
  97.             if((filestat.st_mode & S_IFMT) != S_IFDIR)
  98.             {
  99.             pathptr = rindex(path, '/');
  100.             if(pathptr && path != pathptr) *pathptr = '\0';    
  101.             }
  102.             
  103.             (void)shstrcat(PathBuf, path);
  104.         }
  105.         else
  106.             (void)strcat(PathBuf, path);
  107.         [[[Pasteboard new]
  108.            declareTypes:&NXAsciiPboardType num:1 owner:NULL]
  109.            writeType:NXAsciiPboardType data:PathBuf
  110.            length:strlen(PathBuf)];
  111.         } /* end if(path && length && ... ) */
  112.         else
  113.         *errmsg = "Nothing found on pasteboard.";
  114.         vm_deallocate(task_self(), path, length);
  115.     }  /* end if(types[i]) */
  116.     else
  117.         *errmsg = "No filename/pathname found on pasteboard.";
  118. }
  119.  
  120. // Just puts path to ascii paste board
  121. - copyAsciiPath:(id)pbid userData:(const char *)udata error:(char **)errmsg
  122. {
  123.     addPath(pbid, udata, errmsg, 0);
  124.     return self;
  125. }
  126.  
  127. // Prepends "cd " to path and quotes as needed
  128. - makeCdCommand:(id)pbid userData:(const char *)udata error:(char **)errmsg
  129. {
  130.     addPath(pbid, udata, errmsg, 1);
  131.     return self;
  132. }
  133.  
  134. // Prepends "pushd " to path and quotes as needed
  135. - makePushdCommand:(id)pbid userData:(const char *)udata error:(char **)errmsg
  136. {
  137.     addPath(pbid, udata, errmsg, 2);
  138.     return self;
  139. }
  140.  
  141. @end
  142.  
  143.  
  144. int main(int argc, char *argv[])
  145. {
  146.     id lid;
  147.  
  148.     if (argc>1) _exit(0);        // daemons aren't launched with args!
  149.  
  150.     lid = [[Listener alloc] init];
  151.     [lid setServicesDelegate:[[CopyPath alloc] init]];
  152.     if ([lid checkInAs:"CopyPath"]) _exit(1);    // uh-oh!
  153.     [lid addPort];
  154.     [Listener run];    // never returns
  155.     return 0;
  156. }
  157.